package com.funong.matrix.core.dto;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.funong.matrix.core.enums.ResultCodeEnum;
import com.funong.matrix.core.utils.PageUtil;
import lombok.*;

import java.io.Serializable;
import java.util.List;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class Result<T> implements Serializable {
    private boolean success;
    private String message;
    private int code;
    private T data;


    private long pageNum;
    private long pageSize;
    private long totalCount;
    private long totalPage;

    public static <T> Result<T> success(T data) {
        return Result.<T>builder()
                .success(true)
                .code(ResultCodeEnum.OK.getCode())
                .message(ResultCodeEnum.OK.getMsg())
                .data(data)
                .build();
    }

    public static <T> Result<T> success(String message, T data) {
        return Result.<T>builder()
                .success(true)
                .code(ResultCodeEnum.OK.getCode())
                .message(message)
                .data(data)
                .build();
    }


    public static <T> Result<T> success(T data, Integer pageNo, Integer pageSize, Integer totalCount) {
        return Result.<T>builder()
                .success(true)
                .code(ResultCodeEnum.OK.code())
                .message(ResultCodeEnum.OK.getMsg())
                .data(data)
                .pageNum(pageNo)
                .pageSize(pageSize)
                .totalCount(totalCount)
                .build();
    }

    /**
     * 手动分页
     *
     * @param sourceList
     * @param pageSize
     * @param pageNo
     * @param <T>
     * @return
     */
    public static <T> Result<T> successPage(List<T> sourceList, int pageSize, int pageNo) {
        int totalSize = sourceList.size();
        List<T> resultList = PageUtil.convertPageList(sourceList, pageSize, pageNo);
        return Result.<T>builder()
                .success(true)
                .code(ResultCodeEnum.OK.code())
                .message(ResultCodeEnum.OK.getMsg())
                .data((T) resultList)
                .pageNum(pageNo)
                .pageSize(pageSize)
                .totalCount(totalSize)
                .build();
    }

    public static Result success() {
        return success(null);
    }

    public static Result failure(ResultCodeEnum resultCodeEnum) {
        return Result.builder()
                .success(false)
                .code(resultCodeEnum.getCode())
                .message(resultCodeEnum.getMsg())
                .build();
    }


    public static Result failure(ResultCodeEnum resultCodeEnum, String addMsg) {
        return Result.builder()
                .success(false)
                .code(resultCodeEnum.getCode())
                .message(resultCodeEnum.getMsg() + ":" + addMsg)
                .build();
    }

    public static Result failure(String message) {
        return Result.builder()
                .success(false)
                .code(ResultCodeEnum.BIZ_ERROR.getCode())
                .message(message)
                .build();
    }

    public static Result failure(Integer code, String message) {
        return Result.builder()
                .success(false)
                .code(code)
                .message(message)
                .build();
    }

    public static Result failure(ResultCodeEnum resultCodeEnum, Object data) {
        return Result.builder()
                .success(false)
                .code(resultCodeEnum.getCode())
                .message(resultCodeEnum.getMsg())
                .data(data)
                .build();
    }

    public static Result failure() {
        return Result.builder()
                .success(false)
                .code(ResultCodeEnum.INTERNAL_SERVER_ERROR.getCode())
                .message(ResultCodeEnum.INTERNAL_SERVER_ERROR.getMsg())
                .build();
    }

    public static <T> Result<T> page(IPage<T> pageInfo) {
        return Result.<T>builder()
                .code(ResultCodeEnum.OK.getCode())
                .success(true)
                .message(ResultCodeEnum.OK.getMsg())
                .totalPage(pageInfo.getPages())
                .pageNum(pageInfo.getCurrent())
                .pageSize(pageInfo.getSize())
                .totalCount(pageInfo.getTotal())
                .data((T) pageInfo.getRecords())
                .build();
    }

    public static <T> Result<T> page(Page<T> pageInfo, T data) {
        return Result.<T>builder()
                .code(ResultCodeEnum.OK.getCode())
                .success(true)
                .message(ResultCodeEnum.OK.getMsg())
                .totalPage(pageInfo.getPages())//总页数
                .pageNum(pageInfo.getCurrent())//当前页
                .pageSize(pageInfo.getSize())//每页条数
                .totalCount(pageInfo.getTotal())//总条数
                .data(data)
                .build();
    }

    public static <T> Result<Object> page(IPage<T> pageInfo, Object data) {
        return Result.<Object>builder()
                .code(ResultCodeEnum.OK.getCode())
                .success(true)
                .message(ResultCodeEnum.OK.getMsg())
                .totalPage(pageInfo.getPages())//总页数
                .pageNum(pageInfo.getCurrent())//当前页
                .pageSize(pageInfo.getSize())//每页条数
                .totalCount(pageInfo.getTotal())//总条数
                .data(data)
                .build();
    }

    public static <T> Result<Object> pageSuccess(long pageNum, long pageSize) {
        return Result.builder().code(ResultCodeEnum.OK.getCode())
                .success(true).message(ResultCodeEnum.OK.getMsg())
                .totalPage(0)
                .pageNum(pageNum)
                .pageSize(pageSize)
                .totalCount(0)
                .build();
    }

    public static <T> Result<T> judge(boolean status) {
        if (status) {
            return success();
        } else {
            return failure();
        }
    }

}
